//
//  XMPlayerManager.m
//  XMPlayer
//
//  Created by min on 2017/10/30.
//  Copyright © 2017年 min. All rights reserved.
//

#import "XMPlayerManager.h"
#import <AVFoundation/AVFoundation.h>
#import "XMPlayerConfig.h"
#import "UIView+Extension.h"
#import "XMRefreshView.h"

@interface XMPlayerManager () {
   
    id playerTimeObserver;

    AVPlayer *player;
    AVPlayerItem *playerItem;
    AVPlayerLayer *avplayerLayer;
    
}

/** 背景view */
@property (nonatomic,strong) UIView *BGView;
@property (nonatomic,strong) UIView * ViewLow;

/** 加载时旋转菊花 */
@property(nonatomic, strong) XMRefreshView *refreshView;

/** 临时图片 */
@property (nonatomic,strong) UIImageView *tempView;

/** 是否已经显示 */
@property (nonatomic, assign) BOOL hasShowedFistView;
@property (strong, nonatomic)  UISlider       * mScrubber;     //播放进度
@property (strong, nonatomic)  UIButton * butChange ;
@property (strong, nonatomic)  UILabel * minLabel;
@property (strong, nonatomic)  UILabel * maxLabel ;
@property (strong, nonatomic) UIImageView * imageViewCancel ;
@property (strong, nonatomic) UIButton * butAgain;
@property (strong, nonatomic) UILabel * labelPlay;
@property (assign, nonatomic) CGFloat durationZong;//视频的总的时间
@end

@implementation XMPlayerManager

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.userInteractionEnabled = YES;
        self.backgroundColor = RGBColor(89, 196, 120);
    }
    return self;
}
// 显示
- (void)show{
    
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    
    // 设置背景View
    _BGView = [[UIView alloc] init];
    _BGView.backgroundColor = RGBColor(89, 196, 120);
    _BGView.center = window.center;
    _BGView.bounds = window.bounds;
    _BGView.userInteractionEnabled = YES;
    self.center = CGPointMake(_BGView.bounds.size.width * 0.5, _BGView.bounds.size.height * 0.5);
    self.bounds = CGRectMake(0, 0, _BGView.bounds.size.width, _BGView.bounds.size.height);
    [_BGView addSubview:self];
    
    // 添加到窗口上
    [window addSubview:_BGView];
    //隐藏状态栏
    window.windowLevel = UIWindowLevelStatusBar + 10.0f;
    
    // 添加视频
    [self addVideo];
    
    self.ViewLow = [[UIView alloc]initWithFrame:CGRectMake(0, 90, ScreenWidth, ScreenHeight-140)];
    self.ViewLow.userInteractionEnabled = YES;
    [_BGView addSubview:self.ViewLow];
    //创建手势 使用initWithTarget:action:的方法创建
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapView:)];
    //设置属性
    //tap 手势一共两个属性，一个是设置轻拍次数，一个是设置点击手指个数
    //设置轻拍次数
    tap.numberOfTapsRequired = 2;
    //设置手指字数
    tap.numberOfTouchesRequired = 1;
    //别忘了添加到testView上
    [self.ViewLow addGestureRecognizer:tap];
    
    self.imageViewCancel = [[UIImageView alloc]initWithFrame:CGRectMake(10, 40, 33, 33)];
    self.imageViewCancel.image = [UIImage imageNamed:@"白色取消"];
    self.imageViewCancel.userInteractionEnabled = YES;
    UITapGestureRecognizer * PrivateLetterTap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(cancelBut)];
    [self.imageViewCancel addGestureRecognizer:PrivateLetterTap];
    [_BGView addSubview:self.imageViewCancel];
 
    UIButton * butShare = [[UIButton alloc]initWithFrame:CGRectMake(ScreenWidth-100, 40, 100, 33)];
    [butShare setTitle:@"分享" forState:UIControlStateNormal];
    [butShare setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [butShare addTarget:self action:@selector(clickShareBut) forControlEvents:UIControlEventTouchUpInside];
    [_BGView addSubview:butShare];
 
    self.butAgain = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 60, 60)];
    [self.butAgain setImage:[UIImage imageNamed:@"重新播放"] forState:UIControlStateNormal];
    self.butAgain.hidden = YES;
    [self.butAgain addTarget:self action:@selector(butClickAgain) forControlEvents:UIControlEventTouchUpInside];
    [_BGView addSubview:self.butAgain];
    
    self.labelPlay = [[UILabel alloc]init];
    self.labelPlay.text = @"重新播放";
    self.labelPlay.hidden = YES;
    self.labelPlay.font = FONT_11;
    self.labelPlay.textColor = [UIColor whiteColor];
    self.labelPlay.textAlignment = NSTextAlignmentCenter;
    [_BGView addSubview:self.labelPlay];
    
    [self setUIShare];
 }
#pragma mark - 重新布局
- (void)layoutSubviews{
    [super layoutSubviews];
    if (!_hasShowedFistView) {
        [self showFirstImage];
    }
}
#pragma mark - 显示图片
- (void)showFirstImage{
    UIView *sourceView = [self.sourceImagesContainerView.subviews firstObject];
    CGRect rect = [self.sourceImagesContainerView convertRect:sourceView.frame toView:self];
    UIImageView *tempView = [[UIImageView alloc] init];
    tempView.frame = rect;
    tempView.image = self.currentImage;
    [self addSubview:tempView];
    self.tempView = tempView;
    tempView.contentMode = UIViewContentModeScaleAspectFit;
    
    CGFloat placeImageSizeW = tempView.image.size.width;
    CGFloat placeImageSizeH = tempView.image.size.height;
    CGRect targetTemp;
    
    CGFloat placeHolderH = (placeImageSizeH * WIDTH)/placeImageSizeW;
    if (placeHolderH <= HEIGHT) {
        targetTemp = CGRectMake(0, (HEIGHT - placeHolderH-25) * 0.5 , WIDTH, placeHolderH+25);
    } else {//图片高度>屏幕高度
        targetTemp = CGRectMake(0, 80, WIDTH, placeHolderH-80);
    }
    [UIView animateWithDuration:XMImageAnimationDuration animations:^{
        //将点击的临时imageview动画放大到和目标imageview一样大
        tempView.frame = targetTemp;
        _mScrubber.frame = CGRectMake(50+60, ScreenHeight-45, WIDTH-100-60, 40);

        self.minLabel.frame =  CGRectMake(_mScrubber.frame.origin.x - 50, ScreenHeight-33, 50, 20);
        self.maxLabel.frame = CGRectMake( ScreenWidth-50, ScreenHeight-33, 50, 20);
        self.butAgain.center = tempView.center;
        self.labelPlay.frame = CGRectMake(0, CGRectGetMaxY(self.butAgain.frame)+2, ScreenWidth, 10);
    } completion:^(BOOL finished) {
        //动画完成后，删除临时imageview，让目标imageview显示
        _hasShowedFistView = YES;
    }];
}
-(void)tapView:(UITapGestureRecognizer *)sender{
    //设置轻拍事件改变testView的颜色
    NSLog(@"双击点击 双击点击 双击点击 双击点击");
    [self cancelBut];
}
#pragma mark - 点击退出播放
//- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
-(void)cancelBut{
    self.imageViewCancel.hidden = YES;
    self.labelPlay.hidden = YES;

    UIView *sourceView = [self.sourceImagesContainerView.subviews firstObject];

    CGRect targetTemp = [self.sourceImagesContainerView convertRect:sourceView.frame toView:self];
    self.window.windowLevel = UIWindowLevelNormal;//显示状态栏
    // 移除播放器
    [self removePlayer];
    [UIView animateWithDuration:XMImageAnimationDuration animations:^{
        self.tempView.frame = targetTemp;
        self.backgroundColor = [UIColor clearColor];
        _BGView.backgroundColor = [UIColor clearColor];

    } completion:^(BOOL finished) {
        // 移除
        [self.refreshView removeFromSuperview];
        [self.tempView removeFromSuperview];
        [_BGView removeFromSuperview];
//        [self removeFromSuperview];
    }];
}
#pragma mark - 拖动进度条
-(void)sliderValueChanged:(UISlider *)paramSender{
    if ([paramSender isEqual:self.mScrubber]) {
//        NSLog(@"New value=%f",paramSender.value);
         //当前的分钟数
        NSString * currentTimeStr = [LSZSpecialPackaging convert:paramSender.value];
        self.minLabel.text = [NSString stringWithFormat:@"%@",currentTimeStr];
        [player seekToTime:CMTimeMake(paramSender.value, 1)];
    }
}
#pragma mark - KVO 观察播放进度
- (void)addProgressObserver{
    AVPlayerItem *playerItem = player.currentItem;
    //这里设置每秒执行一次
    __weak __typeof(self) weakself = self;
    playerTimeObserver = [player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        float current = CMTimeGetSeconds(time);
        float total = CMTimeGetSeconds([playerItem duration]);
        NSLog(@"%.2f>>>>",total);
//        NSLog(@"当前已经播放%f",current);
        NSString * currentTimeStr = [LSZSpecialPackaging convert:current];
        weakself.minLabel.text = [NSString stringWithFormat:@"%@",currentTimeStr];
        if (current) {
             weakself.mScrubber.value = current;
//            [player seekToTime:CMTimeMake(current, 1)];
//            [weakself setTime:current withTotal:total];
        }else{
            NSLog(@"111");
        }
    }];
}
- (void)addVideo{
    //1 创建AVPlayerItem
    AVPlayerItem *playerItem = [[AVPlayerItem alloc]initWithURL:[NSURL URLWithString:self.videourl]];
    //2.把AVPlayerItem放在AVPlayer上
    player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
    //3 再把AVPlayer放到 AVPlayerLayer上
    avplayerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
    avplayerLayer.videoGravity = AVLayerVideoGravityResizeAspect;//视频填充模式
    avplayerLayer.frame = _BGView.bounds;
    avplayerLayer.delegate = self;
    //4 最后把 AVPlayerLayer放到self.view.layer上(也就是需要放置的视图的layer层上)
    [_BGView.layer addSublayer:avplayerLayer];
    
    CGFloat w = 40;
    CGFloat x = (_BGView.width - w)/2.0;
    CGFloat y = (_BGView.height - w)/2.0;
    //加载的动画的
    self.refreshView = [XMRefreshView refreshViewWithFrame:CGRectMake(x, y, w, w) logoStyle:RefreshLogoNone];
    [_BGView addSubview:self.refreshView];
    [self.refreshView startAnimation];
    
    _mScrubber = [ [ UISlider alloc ] initWithFrame:CGRectMake(50-60,100,ScreenWidth-100,60) ];//高度设为40就好,高度代表手指触摸的高度.这个一定要注意
    _mScrubber.minimumValue = 0.0;//下限
//    _mScrubber.maximumValue = 1.0;//上限
    _mScrubber.value = 00.00;//开始默认值
    _mScrubber.continuous = YES;
    [_mScrubber addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
    _mScrubber.continuous = NO;//当放开手., 值才确定下来
    [_BGView addSubview:_mScrubber ];
 
    self.butChange = [[UIButton alloc]initWithFrame:CGRectMake(10, ScreenHeight-40, 35, 35)];
    [self.butChange setImage:[UIImage imageNamed:@"播放"] forState:UIControlStateNormal];
    self.butChange.tag = 1;
    [self.butChange addTarget:self action:@selector(clickButChange:) forControlEvents:UIControlEventTouchUpInside];
    [_BGView addSubview:self.butChange];
    // 最小值label
    self.minLabel = [[UILabel alloc] initWithFrame:CGRectMake(_mScrubber.frame.origin.x - 20-60, ScreenHeight-30, 20, 20)];
    self.minLabel.textColor = [UIColor whiteColor];
    self.minLabel.textAlignment = NSTextAlignmentCenter;
    self.minLabel.text = [NSString stringWithFormat:@"0.00"];
    [_BGView addSubview:self.minLabel];
     // 最大值label
    self.maxLabel = [[UILabel alloc] initWithFrame:CGRectMake(_mScrubber.frame.origin.x + _mScrubber.frame.size.width + 5,ScreenHeight-33, 30, 20)];
    self.maxLabel.textAlignment = NSTextAlignmentCenter;
    self.maxLabel.textColor = [UIColor whiteColor];
    [_BGView addSubview:self.maxLabel];
    
    [self addProgressObserver];
    /**以上是基本的播放界面，但是没有前进后退**/
    //观察是否播放，KVO进行观察，观察
//    playerItem.loadedTimeRanges
    [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
    [playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
    [playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
    [playerItem addObserver:self forKeyPath:@"playbackBufferFull" options:NSKeyValueObservingOptionNew context:nil];
 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished) name:AVPlayerItemDidPlayToEndTimeNotification object:player.currentItem];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playFailed2) name:AVPlayerItemFailedToPlayToEndTimeNotification object:player.currentItem];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playFailed) name:AVPlayerItemFailedToPlayToEndTimeErrorKey object:player.currentItem];
}
#pragma mark- 播放还是暂停
-(void)clickButChange:(UIButton *)but
{
    if (but.tag == 1) {
        //暂停
        NSLog(@"暂停");
        [player pause];
        [self.butChange setImage:[UIImage imageNamed:@"暂停"] forState:UIControlStateNormal];
        self.butChange.tag = 2;
    }else{
        [player play];
        [self.butChange setImage:[UIImage imageNamed:@"播放"] forState:UIControlStateNormal];
        self.butChange.tag = 1;
    }
}
#pragma mark - 重新播放
-(void)butClickAgain
{
    [player seekToTime:CMTimeMake(0, 1)];
    [player play];
    self.butAgain.hidden = YES;
    self.labelPlay.hidden = YES;
}
#pragma mark - 播放结束
- (void)playbackFinished{
    // 播放结束重复播放
    self.butAgain.hidden = NO;
    self.labelPlay.hidden = NO;
    [player seekToTime:kCMTimeZero];
    self.mScrubber.value = 0.00;
}
// 播放失败
-(void)playFailed2{
    [player pause];
    // 结束刷新
    [self endAnimation];
}
-(void)playFailed{
    [player pause];
    // 结束刷新
    [self endAnimation];
}
/*
 * 执行观察者方法
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    AVPlayerItem *playerItems = (AVPlayerItem *)object;
    if ([keyPath isEqualToString:@"status"]) {
        AVPlayerStatus status = [[change objectForKey:@"new"] intValue]; // 获取更改后的状态
        if (status == AVPlayerStatusReadyToPlay) {
            //status 点进去看 有三种状态
            CGFloat duration = playerItems.duration.value / playerItems.duration.timescale; //视频总时间
            self.durationZong = duration;
            _mScrubber.maximumValue = self.durationZong ;//上限
             NSString * timeZong = [LSZSpecialPackaging convert:duration];
            self.maxLabel.text = timeZong;
//            NSLog(@"准备好播放了，总时间：%@", timeZong);
        } else if (status == AVPlayerStatusFailed) {
//            NSLog(@"AVPlayerStatusFailed");
            [player pause];
            // 结束刷新
            [self endAnimation];
        } else {
//            NSLog(@"AVPlayerStatusUnknown");
            [player pause];
            // 结束刷新
            [self endAnimation];
        }
    }else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {  //监听播放器的下载进度
        
        NSArray *loadedTimeRanges = [playerItems loadedTimeRanges];
        CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域
        float startSeconds = CMTimeGetSeconds(timeRange.start);
        float durationSeconds = CMTimeGetSeconds(timeRange.duration);
        NSTimeInterval timeInterval = startSeconds + durationSeconds;// 计算缓冲总进度
        CMTime duration = playerItems.duration;
        CGFloat totalDuration = CMTimeGetSeconds(duration);
        NSLog(@"下载进度：%.2f", timeInterval / totalDuration);
    } else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) { //监听播放器在缓冲数据的状态
//        NSLog(@"缓冲不足暂停了");
        [player pause];
        [self startAnimation];
    } else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {
//        NSLog(@"缓冲达到可播放程度了");
        //由于 AVPlayer 缓存不足就会自动暂停，所以缓存充足了需要手动播放，才能继续播放
        // 结束刷新
        [self endAnimation];
        // 播放
        [player play];
    } else if ([keyPath isEqualToString:@"playbackBufferFull"]) {
//        NSLog(@"缓冲区满了");
    }
}
// 释放
- (void)dealloc {
     // 移除所有通知
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
// 移除播放器
- (void)removePlayer{
    [player pause];
    [player setRate:0];
    [player.currentItem removeObserver:self forKeyPath:@"status" context:nil];
    [player.currentItem removeObserver:self forKeyPath:@"loadedTimeRanges" context:nil];
    [player.currentItem removeObserver:self forKeyPath:@"playbackBufferEmpty" context:nil];
    [player.currentItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp" context:nil];
    [player.currentItem removeObserver:self forKeyPath:@"playbackBufferFull" context:nil];
    [player replaceCurrentItemWithPlayerItem:nil];
    playerItem = nil;
    player = nil;
}
// 开始旋转
- (void)startAnimation{
    [self.refreshView startAnimation];
    self.refreshView.hidden = NO;
}
// 结束旋转
- (void)endAnimation{
    [self.refreshView stopAnimation];
    self.refreshView.hidden = YES;
}
// videoPath为视频下载到本地之后的本地路径
- (void)saveVideo:(NSString *)videoPath{
//    if (_videoPath) {
//
//        if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum([_videoPath path])) {
//            //保存相册核心代码
//            UISaveVideoAtPathToSavedPhotosAlbum([_videoPath path], self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
//        }
//
//    }
}
//保存视频完成之后的回调
- (void) savedPhotoImage:(UIImage*)image didFinishSavingWithError: (NSError *)error contextInfo: (void *)contextInfo {
    if (error) {
        NSLog(@"保存视频失败%@", error.localizedDescription);
    }else {
        NSLog(@"保存视频成功");
    }
}
-(void)setUIShare
{
    self.viewShare = [[UIView alloc]initWithFrame:CGRectMake(0, ScreenHeight-150, ScreenWidth, 150)];
     self.viewShare.hidden = YES;
     self.viewShare.backgroundColor = [UIColor whiteColor];
    [_BGView addSubview: self.viewShare];
    
    UIButton * butpy = [[UIButton alloc]initWithFrame:CGRectMake(20, 10, 80, 80)];
    [butpy setImage:[UIImage imageNamed:@"分享_微信好友"] forState:UIControlStateNormal];
    [butpy addTarget:self action:@selector(clickPyBut) forControlEvents:UIControlEventTouchUpInside];
    [self.viewShare addSubview:butpy];
    
    UIButton * butCircleFriends = [[UIButton alloc]initWithFrame:CGRectMake(CGRectGetMaxX(butpy.frame)+20, 10, 80, 80)];
    [butCircleFriends setImage:[UIImage imageNamed:@"分享_朋友圈"] forState:UIControlStateNormal];
    [butCircleFriends addTarget:self action:@selector(clickButCircleFriends) forControlEvents:UIControlEventTouchUpInside];
    [self.viewShare addSubview:butCircleFriends];
    
    UIButton * buttonCancelShare = [[UIButton alloc]initWithFrame:CGRectMake(0, self.viewShare.frame.size.height-50, ScreenWidth, 50)];
    buttonCancelShare.backgroundColor = RGBColor(89, 196, 120);
    [buttonCancelShare setTitle:@"取消" forState:UIControlStateNormal];
    [buttonCancelShare addTarget:self action:@selector(clickCancelShare) forControlEvents:UIControlEventTouchUpInside];
    [self.viewShare addSubview:buttonCancelShare];
}
#pragma mark - 分享
-(void)clickShareBut
{
     if (self.viewShare.hidden == YES) {
        self.viewShare.hidden = NO;
    }else{
        self.viewShare.hidden = YES;
    }
 
}
-(void)clickCancelShare
{
    self.viewShare.hidden = YES;
}
-(void)clickPyBut
{
    [LSZSpecialPackaging shareWXWithViewController:self.videourl title:self.titleStr type:0];
//    [LSZSpecialPackaging shareWXWithViewController:self.shareURL title:self.titleStr type:0];
}
-(void)clickButCircleFriends
{
    [LSZSpecialPackaging shareWXWithViewController:self.videourl title:self.titleStr type:1];
//    [LSZSpecialPackaging shareWXWithViewController:self.shareURL title:self.titleStr type:1];
}
@end
